<template>
  <div class="region-select">
    <!-- 有标签模式 -->
    <el-form-item :label="label || '所属地区'" v-if="showLabel">
      <div class="region-selects">
        <el-cascader
          v-model="selectedRegions"
          :options="regionOptions"
          :props="cascaderProps"
          :disabled="disabled"
          :loading="loading"
          filterable
          clearable
          placeholder="请选择所属地区"
          @change="handleRegionChange"
          style="width: 100%"
          class="region-cascader">
          <template slot="empty">
            <div class="cascader-empty">
              <i class="el-icon-map-location"></i>
              <p>暂无地区数据</p>
            </div>
          </template>
        </el-cascader>
      </div>
    </el-form-item>

    <div v-else class="region-selects">
      <el-cascader
        v-model="selectedRegions"
        :options="regionOptions"
        :props="cascaderProps"
        :disabled="disabled"
        :loading="loading"
        filterable
        clearable
        placeholder="请选择所属地区"
        @change="handleRegionChange"
        style="width: 100%"
        class="region-cascader">
        <template slot="empty">
          <div class="cascader-empty">
            <i class="el-icon-map-location"></i>
          </div>
        </template>
      </el-cascader>
    </div>
  </div>
</template>

<script>
import { getProvinces, getCities, getDistricts } from '@/api/management/region'

export default {
  name: 'RegionSelect',
  props: {
    value: {
      type: Object,
      default: () => ({})
    },
    disabled: {
      type: Boolean,
      default: false
    },
    showLabel: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    }
  },
  data() {
    return {

      selectedRegions: [],

      cascaderProps: {
        value: 'code',
        label: 'name',
        children: 'children',
        checkStrictly: false,
        lazy: true,
        lazyLoad: this.loadRegionData,
        expandTrigger: 'hover'
      },

      regionCache: {
        provinces: new Map(),
        cities: new Map(),
        districts: new Map()
      },

      loading: false
    }
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          this.initValue(val)
        }
      },
      immediate: true
    }
  },
  created() {
    this.loadInitialData()
  },
  methods: {
    async loadInitialData() {
      try {
        this.loading = true
        const response = await getProvinces()
        if (response.code === 200) {
          const provinces = this.formatProvinceData(response.data || response.rows || [])
          provinces.forEach(province => {
            province.level = 'province'
            province.leaf = false
          })
          this.regionOptions = provinces
          this.cacheProvinceData(provinces)
        }
      } catch (error) {
      } finally {
        this.loading = false
      }
    },


    formatProvinceData(data) {
      return data.map(item => ({
        code: String(item.provinceId || item.code || item.id),
        name: item.name || item.provinceName,
        leaf: false,
        level: 'province',
        children: []
      }))
    },


    formatCityData(data, parentCode) {
      return data.map(item => ({
        code: String(item.cityId || item.code || item.id),
        name: item.name || item.cityName,
        parentCode: String(parentCode),
        leaf: false,
        level: 'city',
        children: []
      }))
    },

    formatDistrictData(data, parentCode) {
      return data.map(item => ({
        code: String(item.countyId || item.code || item.id),
        name: item.name || item.districtName,
        parentCode: String(parentCode),
        leaf: true,
        level: 'district'
      }))
    },

    cacheProvinceData(provinces) {
      provinces.forEach(province => {
        this.regionCache.provinces.set(province.code, province)
      })
    },

    cacheCityData(cities) {
      cities.forEach(city => {
        this.regionCache.cities.set(city.code, city)
      })
    },

    cacheDistrictData(districts) {
      districts.forEach(district => {
        this.regionCache.districts.set(district.code, district)
      })
    },

    async loadRegionData(node, resolve) {
      if (!node || !node.data) {
        resolve(this.regionOptions)
        return
      }

      const { level, code } = node.data

      if (!code) {
        console.warn('地区编码不能为空')
        resolve([])
        return
      }

      try {
        if (level === 'province') {
          // 加载城市数据
          const response = await getCities(code)
          if (response.code === 200) {
            const cities = this.formatCityData(response.data || response.rows || [], code)
            this.cacheCityData(cities)
            resolve(cities)
          } else {
            resolve([])
          }
        } else if (level === 'city') {
          // 加载区县数据
          const response = await getDistricts(code)
        if (response.code === 200) {
            const districts = this.formatDistrictData(response.data || response.rows || [], code)
            this.cacheDistrictData(districts)
            resolve(districts)
          } else {
            resolve([])
          }
        } else {
          resolve([])
        }
      } catch (error) {
        console.error('加载地区数据失败:', error)
        this.$message.error('加载地区数据失败，请刷新重试')
        resolve([])
      }
    },

    // 初始化值
    async initValue(val) {
      if (!val) return

      try {
        if (this.regionOptions.length === 0) {
          await this.loadInitialData()
        }

        const codes = []
        if (val.provinceId) {
          const provinceId = String(val.provinceId)
          codes.push(provinceId)

          const cityResponse = await getCities(provinceId)
          if (cityResponse.code === 200 && val.cityId) {
            const cities = this.formatCityData(cityResponse.data || cityResponse.rows || [], provinceId)
            const province = this.regionOptions.find(p => p.code === provinceId)
            if (province) {
              province.children = cities
            }
            this.cacheCityData(cities)

            const cityId = String(val.cityId)
            codes.push(cityId)

            if (val.countyId) {
              const districtResponse = await getDistricts(cityId)
              if (districtResponse.code === 200) {
                const districts = this.formatDistrictData(districtResponse.data || districtResponse.rows || [], cityId)
                const city = cities.find(c => c.code === cityId)
                if (city) {
                  city.children = districts
                }
                this.cacheDistrictData(districts)

                const countyId = String(val.countyId)
                codes.push(countyId)
              }
            }
          }
        }

        this.$nextTick(() => {
          this.selectedRegions = codes
        })
      } catch (error) {
        this.$message.error('初始化地区数据失败，请刷新重试')
      }
    },

    handleRegionChange(value) {
      if (!value || !value.length) {
        this.emitEmpty()
        return
      }

      const [provinceCode, cityCode, districtCode] = value
      const province = this.regionCache.provinces.get(provinceCode)
      const city = this.regionCache.cities.get(cityCode)
      const district = this.regionCache.districts.get(districtCode)

        const result = {
        provinceId: provinceCode || '',
        cityId: cityCode || '',
        countyId: districtCode || '',
          townId: '',
        provinceName: province?.name || '',
        cityName: city?.name || '',
        districtName: district?.name || '',
          streetName: ''
      }

      this.$emit('input', result)
      this.$emit('change', result)
    },

    emitEmpty() {
      const emptyResult = {
        provinceId: '',
        provinceName: '',
        cityName: '',
        districtName: '',
        streetName: ''
      }
      this.$emit('input', emptyResult)
      this.$emit('change', emptyResult)
    },

    reset() {
      this.selectedRegions = []
      this.emitEmpty()
    }
  }
}
</script>

<style lang="scss" scoped>
.region-select {
  width: 100%;

  .region-selects {
    width: 100%;

    .region-cascader {
      width: 100%;

      :deep(.el-input__inner) {
        border-radius: 4px;
        height: 36px;
        font-size: 14px;
        transition: all 0.3s;

        &:hover {
          border-color: #b3d8ff;
        }

        &:focus {
          border-color: #409EFF;
          box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
        }
      }

      :deep(.el-cascader__dropdown) {
        border-radius: 4px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      }
    }
  }
}

.cascader-empty {
  text-align: center;
  padding: 20px 0;
  color: #909399;

  i {
    font-size: 24px;
    margin-bottom: 8px;
    color: #c0c4cc;
  }

  p {
    margin: 0;
    font-size: 14px;
  }
}
</style>
